#ifndef _EXAMPLE_TALKER_NODE_
#define _EXAMPLE_TALKER_NODE_

#include <iostream>

#include <rclcpp/rclcpp.hpp>
#include <rclcpp_components/register_node_macro.hpp>

#include <sensor_msgs/msg/point_cloud2.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <geometry_msgs/msg/pose.hpp>

#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/transform_listener.h>
#include <tf2_ros/transform_broadcaster.h>
#include <tf2_eigen/tf2_eigen.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <tf2_ros/static_transform_broadcaster.h>

#include <tf2_ros/buffer.h>
#include <tf2_ros/transform_listener.h>
#include "rclcpp/time.hpp"
#include <rclcpp/time_source.hpp>

#include <cv_bridge/cv_bridge.h>

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/calib3d.hpp"
#include <opencv2/highgui.hpp>

#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/search/impl/search.hpp>
#include <pcl/range_image/range_image.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/common/common.h>
#include <pcl/common/transforms.h>
#include <pcl/registration/icp.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/filter.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/crop_box.h>
#include <pcl_conversions/pcl_conversions.h>

// mars_rover::listener::ListenerNode

namespace mars_rover
{
  namespace listener
  {
    class ListenerNode : public rclcpp::Node
    {
    private:
      rclcpp::Subscription<sensor_msgs::msg::Image>::SharedPtr sub_image;
      rclcpp::Subscription<sensor_msgs::msg::PointCloud2>::SharedPtr sub_pointCloud2;
	    rclcpp::Subscription<geometry_msgs::msg::PoseStamped>::SharedPtr sub_pose;

      std::shared_ptr<tf2_ros::StaticTransformBroadcaster> static_tf_broadcaster_;

      std::shared_ptr<tf2_ros::TransformListener> tf_listener_{nullptr};
      std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
      
      std::string source_frame_;
      std::string target_frame_;

      geometry_msgs::msg::PointStamped source_point_;
      geometry_msgs::msg::PointStamped target_point_;

    public:
      explicit ListenerNode(const rclcpp::NodeOptions &options);
      void topic_image_callback(const sensor_msgs::msg::Image::SharedPtr msg);
      void topic_pointcloud_callback(const sensor_msgs::msg::PointCloud2::SharedPtr msg);
      void topic_pose_callback(const geometry_msgs::msg::PoseStamped::SharedPtr msg);
    };
  } // namespace listener
} // namespace mars_rover


#endif